from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.Qt import *
from PyQt5.Qt import QThread
import cv2 
import json
import time
import numpy as np
import logging
import multiprocessing

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

kernel_2 = np.ones((2, 2), np.uint8)  # 2x2的卷积核
kernel_3 = np.ones((3, 3), np.uint8)  # 3x3的卷积核
kernel_4 = np.ones((4, 4), np.uint8)  # 4x4的卷积核
kernel_8 = np.ones((8, 8), np.uint8)

draw_color = (0,255,0)

Lower_red = np.array([0, 61, 136])    #red
Upper_red = np.array([5, 255, 255])
draw_red = draw_color
red = [Lower_red, Upper_red, 'red',draw_red]

Lower_green = np.array([39, 60, 133])
Upper_green = np.array([96, 255, 255])
draw_green =draw_color
green = [Lower_green, Upper_green, 'green',draw_green]

Lower_blue = np.array([67, 91, 170])
Upper_blue = np.array([113, 193, 255])
draw_blue =draw_color
blue = [Lower_blue, Upper_blue, 'blue',draw_blue]

Lower_yellow = np.array([21, 103, 63])   
Upper_yellow = np.array([37, 255, 255])
draw_yellow = draw_color
yellow = [Lower_yellow, Upper_yellow, 'yellow',draw_yellow]

color_list = [red,blue,green,yellow]
camera_nun = 0

class Camera_Thread(QThread):

    cap_signal = pyqtSignal(str)

    def __init__(self,label,gui_signal):
        super().__init__()
        self.stop = False
        self.Is_exit = False
        self.cap= None
        self.frame = None
        self.label = label

        self.gui_signal=gui_signal
        self.cap_signal.connect(self.cap_camera)

        self.count_pos = 0
        self.program_flag = 0

    def exit(self):
        self.stop = True
        self.Is_exit= True
    
    #### 由于OCR的CPU占用率较高，为不影响主线程运行，单起子程序运行
    def ocr_subProcess(self, img):
        self.frame_counter += 1
        if self.frame_counter >= self.ocr_interval:
            ocr_process = multiprocessing.Process(target= self.ocr_test, args=(img,))
            ocr_process.start()
            self.frame_counter = 0

    #### APP 
    def ocr_test(self,img):
        try:
            pass

        except Exception as e:
            logger.error(e,exc_info=True)

    #### 二维码识别
    def QR_test(self,img):
        try:
            pass

        except Exception as e:
            logger.error(e,exc_info=True)

    #### 形状识别
    def contour_recong(self,frame):
        try:
            pass

        except Exception as e:
            logger.error(e,exc_info=True)

    # 颜色识别
    def color_recong(self,frame):
        try:
            pass

        except Exception as e:
            logger.error(e,exc_info=True)

    #### 展示图片
    def display(self,):
        try:
            #### 原图缩放
            # width_ori, height_ori = self.frame.shape[:2]
            # print(f"width_ori is {width_ori}, height_ori is {height_ori}")
            # width_dst = int(width_ori * 0.39)  
            # height_dst = int(height_ori * 0.41)
            # resized_image  = cv2.resize(self.frame, (width_dst, height_dst), interpolation=cv2.INTER_LINEAR)
            rgb_img = cv2.cvtColor(self.frame,cv2.COLOR_BGR2RGB)
            
            ####将rgb格式转换为qt可以识别的格式
            img_dis = QImage(rgb_img,rgb_img.shape[1],rgb_img.shape[0],QImage.Format_RGB888)
            ####加载图片，并设定图片大小
            img_dis = QPixmap(img_dis)
            ####显示图片--- 将图片放到label中心
            self.label.setAlignment(QtCore.Qt.AlignCenter) 
            self.label.setPixmap(img_dis)
            time.sleep(0.001)
        except Exception as e:
            logger.error(e,exc_info=True)

    def run(self): 
        self.cap = cv2.VideoCapture(camera_nun)
        self.cap.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc('M','J','P','G')) 

        while not self.Is_exit:
            while not self.stop:
                try:
                    # 获取摄像头捕获的画面帧，返回ret和frame
                    # ret的True/False反映是否捕获成功，frame是画面
                    ret, self.frame = self.cap.read()
                    if not ret:
                        self.gui_signal.emit(json.dumps({"source":2,}))
                        time.sleep(2)
                        self.cap = cv2.VideoCapture(camera_nun)
                        self.cap.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc('M','J','P','G')) 
      
                    # 在窗口中显示处理之后的画面
                    if ret:
                        #### 对图片进行裁剪
                        height,width,channel = self.frame.shape
                        new_width, new_height = height, width
                        resized_frame = cv2.resize(self.frame, (new_width, new_height), interpolation=cv2.INTER_LINEAR)
                        image = resized_frame
                        
                        #### 进行颜色检测识别--垃圾分拣
                        if self.program_flag ==0:
                            self.color_recong(image)
                        
                        #### 进行轮廓检测识别
                        elif self.program_flag == 1:
                            self.contour_recong(image)  
                        
                        #### 进行二维码识别
                        elif self.program_flag == 2:
                            self.QR_test(image)   
                        
                        #### 进行OCR检测识别
                        elif self.program_flag == 3:
                            self.ocr_test(image)  

                        self.display()
                        time.sleep(0.1)
                
                except Exception as e:
                    logger.error(e,exc_info=True)

    def cap_camera(self,msg):
        message_json = json.loads(msg)
        camera_num = int(message_json.get("camera_num"))
        if camera_num == 0 or camera_num ==1 or camera_num ==2 or camera_num ==9:
            self.cap = cv2.VideoCapture(camera_num)
            ret, frame = self.cap.read()
            if ret :
                self.stop = 0
                self.gui_signal.emit(json.dumps({"source":0,"camera_num":camera_num}))
            else:
                self.gui_signal.emit(json.dumps({"source":3,"camera_num":camera_num}))
        else:
            #### 返回主线程：摄像头编号是0，1，2，3
            self.gui_signal.emit(json.dumps({"source":1}))

              